package com.jfcloud.mall.user.service.impl;

import java.time.LocalDateTime;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jfcloud.common.exception.BussinessException;
import com.jfcloud.mall.user.domain.JfcloudUser;
import com.jfcloud.mall.user.domain.JfcloudUserJwt;
import com.jfcloud.mall.user.domain.dto.GrantParams;
import com.jfcloud.mall.user.persistent.JfcloudUserJwtService;
import com.jfcloud.mall.user.persistent.JfcloudUserService;
import com.jfcloud.mall.user.service.TokenService;

/**
 * jwt 非加密模式
 * @author zhaojunfu
 *
 */
@Service(value = "JwtTokenServiceImpl")
@Transactional
public class JwtTokenServiceImpl implements TokenService {
	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTokenServiceImpl.class);

	/*
	 * jwt 签名密钥
	 * 可在本地配置文件或者配置中心进行配置
	 */
	@Value("${jfcloud.jwt.sign:zjf2020}")
	private String sign;

	@Autowired
	private JfcloudUserService jfcloudUserService;
	@Autowired
	private JfcloudUserJwtService jfcloudUserJwtService;

	@Override
	public Object grant(GrantParams params) throws Exception {
		// 1.参数校验
		String username = params.getUsername();
		String password = params.getPassword();
		Assert.notNull(username, "用户名不能为空");
		Assert.notNull(password, "密码不能为空");

		// 2.认证
		JfcloudUser user = null;
		try {
			user = jfcloudUserService.getOne(new QueryWrapper<JfcloudUser>().eq("username", username));
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			throw new BussinessException("账号异常");
		}

		Assert.notNull(user, "账号不存在");
		String dbPwd = user.getPassword();
		if (password.equals(dbPwd)) {
			// 验证通过
			
			String token = "";
			user.setPassword("");
			token = JWT.create().withClaim("userInfo",fillNull( BeanUtils.describe(user) ))
					.sign(Algorithm.HMAC256(sign));

			JfcloudUserJwt jwt = new JfcloudUserJwt();
			jwt.setUserId(user.getId());
			jwt.setCreateTime(LocalDateTime.now());
			jwt.setStatus(1);
			jwt.setJwtToken(token);
			jfcloudUserJwtService.save(jwt);
			
			return token;
		} else {
			// 验证不通过
			throw new BussinessException("密码不正确");
		}

	}


	private Map<String,String> fillNull(Map<String, String> describe) {
		for(String k :describe.keySet()) {
			String v  = describe.get(k);
			if(v==null) {
				describe.put(k, "");
			}
		}
		return describe;
	}


	@Override
	public Object validateAndGet(Object token) {
		JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(sign)).build();
		try {
			jwtVerifier.verify(String.valueOf(token));
			Map<String,Object> userMap = JWT.decode(String.valueOf(token)).getClaim("userInfo").asMap();
			return userMap;
		} catch (JWTVerificationException e) {
			LOGGER.info("jwt 验证失败 "+e.getMessage());
			throw e;
		}
	}

}
